package com.yuanqi.controller;
import com.yuanqi.pojo.Customer;
import com.yuanqi.pojo.SalesOrder;
import com.yuanqi.service.CustomerService;
import com.yuanqi.service.SalesOrderService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.Date;
import java.util.ArrayList;
import java.util.List;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;

@RestController
@RequestMapping("/api/sales")
public class CustomerController {

    @Resource
    private CustomerService customerService;
    @Resource
    private SalesOrderService salesOrderService;

    @GetMapping("/customer/page")
    public Object page(@RequestParam(required = false) Integer pageNo,
                       @RequestParam(required = false) Integer pageSize,
                       @RequestParam(required = false) String customerName,
                       @RequestParam(required = false) Integer status,
                       @RequestParam(required = false) Long ownerEmployeeId) {
        return customerService.pageWithAssoc(pageNo, pageSize, customerName, status, ownerEmployeeId);
    }

    @PostMapping("/customer")
    public boolean create(@RequestBody Customer customer) {
        customer.setCreatedAt(new Date());
        customer.setUpdatedAt(new Date());
        if (customer.getStatus() == null) customer.setStatus(1);
        return customerService.save(customer);
    }

    @PutMapping("/customer/{id}")
    public boolean update(@PathVariable Long id, @RequestBody Customer customer) {
        customer.setId(id);
        customer.setUpdatedAt(new Date());
        return customerService.updateById(customer);
    }

    @DeleteMapping("/customer/{id}")
    public boolean delete(@PathVariable Long id) {
        // 若存在外键引用，禁止直接删除
        Long cnt = salesOrderService.lambdaQuery().eq(SalesOrder::getCustomerId, id).count();
        if (cnt != null && cnt > 0) {
            return false;
        }
        return customerService.removeById(id);
    }

    /** 批量删除（兼容多种传参）：
     * 1) DELETE /api/sales/customer/batch?ids=1&ids=2
     * 2) DELETE /api/sales/customer/batch?idsCsv=1,2,3
     */
    @DeleteMapping("/customer/batch")
    public java.util.Map<String, Object> deleteBatch(
            @RequestParam(value = "ids", required = false) List<Long> ids,
            @RequestParam(value = "idsCsv", required = false) String idsCsv) {
        if ((ids == null || ids.isEmpty()) && idsCsv != null && !idsCsv.isEmpty()) {
            ids = new java.util.ArrayList<>();
            for (String s : idsCsv.split(",")) {
                try { ids.add(Long.parseLong(s.trim())); } catch (Exception ignored) {}
            }
        }
        java.util.Map<String, Object> resp = new java.util.HashMap<>();
        if (ids == null || ids.isEmpty()) {
            resp.put("success", false);
            resp.put("deleted", 0);
            resp.put("message", "未选择要删除的客户");
            return resp;
        }
        // 检查引用的销售订单
        Long ref = salesOrderService.lambdaQuery().in(SalesOrder::getCustomerId, ids).count();
        if (ref != null && ref > 0) {
            resp.put("success", false);
            resp.put("deleted", 0);
            resp.put("message", "存在关联销售订单的客户，无法删除");
            return resp;
        }
        boolean success = customerService.removeByIds(ids);
        resp.put("success", success);
        resp.put("deleted", success ? ids.size() : 0);
        return resp;
    }

    /** 批量删除（POST JSON）：{"ids":[1,2,3]} 或 [1,2,3] */
    @PostMapping("/customer/batch")
    public java.util.Map<String, Object> deleteBatchPost(@RequestBody Object body) {
        java.util.List<Long> ids = new java.util.ArrayList<>();
        if (body instanceof java.util.List) {
            for (Object o : (java.util.List<?>) body) { try { ids.add(Long.valueOf(String.valueOf(o))); } catch (Exception ignored) {} }
        } else if (body instanceof java.util.Map) {
            Object v = ((java.util.Map<?,?>) body).get("ids");
            if (v instanceof java.util.List) {
                for (Object o : (java.util.List<?>) v) { try { ids.add(Long.valueOf(String.valueOf(o))); } catch (Exception ignored) {} }
            }
        }
        java.util.Map<String, Object> resp = new java.util.HashMap<>();
        if (ids.isEmpty()) {
            resp.put("success", false);
            resp.put("deleted", 0);
            resp.put("message", "未选择要删除的客户");
            return resp;
        }
        Long ref = salesOrderService.lambdaQuery().in(SalesOrder::getCustomerId, ids).count();
        if (ref != null && ref > 0) {
            resp.put("success", false);
            resp.put("deleted", 0);
            resp.put("message", "存在关联销售订单的客户，无法删除");
            return resp;
        }
        boolean success = customerService.removeByIds(ids);
        resp.put("success", success);
        resp.put("deleted", success ? ids.size() : 0);
        return resp;
    }

    @GetMapping("/customer/{id}")
    public Customer detail(@PathVariable Long id) {
        return customerService.getById(id);
    }

    @GetMapping("/customer/export")
    public ResponseEntity<byte[]> exportExcel(@RequestParam(required = false) String customerName,
                                              @RequestParam(required = false) Integer status) throws Exception {
        List<Customer> list = customerService.lambdaQuery()
                .like(customerName != null && !customerName.isEmpty(), Customer::getCustomerName, customerName)
                .eq(status != null, Customer::getStatus, status)
                .list();

        Workbook wb = new XSSFWorkbook();
        Sheet sheet = wb.createSheet("客户");
        String[] headers = {"ID","客户编码","客户名称","联系人","电话","邮箱","税号","开票地址","收货地址","信用额度","账期天数","状态","负责人","创建时间"};
        Row header = sheet.createRow(0);
        for (int i=0;i<headers.length;i++) {
            header.createCell(i).setCellValue(headers[i]);
            sheet.setColumnWidth(i, 18*256);
        }
        int rowIdx = 1;
        for (Customer c : list) {
            Row r = sheet.createRow(rowIdx++);
            int col=0;
            r.createCell(col++).setCellValue(c.getId()==null?0:c.getId());
            r.createCell(col++).setCellValue(s(c.getCustomerCode()));
            r.createCell(col++).setCellValue(s(c.getCustomerName()));
            r.createCell(col++).setCellValue(s(c.getContactName()));
            r.createCell(col++).setCellValue(s(c.getPhone()));
            r.createCell(col++).setCellValue(s(c.getEmail()));
            r.createCell(col++).setCellValue(s(c.getTaxNo()));
            r.createCell(col++).setCellValue(s(c.getBillingAddress()));
            r.createCell(col++).setCellValue(s(c.getShippingAddress()));
            r.createCell(col++).setCellValue(c.getCreditLimit()==null?0:c.getCreditLimit().doubleValue());
            r.createCell(col++).setCellValue(c.getPaymentTermDays()==null?0:c.getPaymentTermDays());
            r.createCell(col++).setCellValue(c.getStatus()==null?0:c.getStatus());
            r.createCell(col++).setCellValue(c.getFuId()==null?"":String.valueOf(c.getFuId()));
            r.createCell(col++).setCellValue(c.getCreatedAt()==null?"":c.getCreatedAt().toString());
        }
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        wb.write(bos);
        wb.close();
        byte[] bytes = bos.toByteArray();
        String filename = java.net.URLEncoder.encode("客户列表.xlsx", StandardCharsets.UTF_8.name());
        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename="+filename)
                .contentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))
                .body(bytes);
    }

    @PostMapping(value = "/customer/import", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public Object importExcel(@RequestParam("file") MultipartFile file) throws Exception {
        Workbook wb = new XSSFWorkbook(file.getInputStream());
        Sheet sheet = wb.getSheetAt(0);
        DataFormatter fmt = new DataFormatter();
        List<Customer> toSave = new ArrayList<>();
        for (int i = 1; i <= sheet.getLastRowNum(); i++) {
            Row r = sheet.getRow(i);
            if (r == null) continue;
            String code = getCell(r,1,fmt);
            String name = getCell(r,2,fmt);
            if ((code==null||code.isEmpty()) && (name==null||name.isEmpty())) continue;
            Customer c = new Customer();
            // 与导出列顺序一致
            c.setCustomerCode(code);
            c.setCustomerName(name);
            c.setContactName(getCell(r,3,fmt));
            c.setPhone(getCell(r,4,fmt));
            c.setEmail(getCell(r,5,fmt));
            c.setTaxNo(getCell(r,6,fmt));
            c.setBillingAddress(getCell(r,7,fmt));
            c.setShippingAddress(getCell(r,8,fmt));
            c.setCreditLimit(parseDecimal(getCell(r,9,fmt)));
            c.setPaymentTermDays(parseInt(getCell(r,10,fmt)));
            c.setStatus(parseInt(getCell(r,11,fmt)) == null ? 1 : parseInt(getCell(r,11,fmt)));
            c.setFuId(parseLong(getCell(r,12,fmt)));
            c.setCreatedAt(new Date());
            c.setUpdatedAt(new Date());
            toSave.add(c);
        }
        wb.close();
        customerService.saveBatch(toSave);
        return toSave.size();
    }

    private static String s(Object o){
        return o==null?"":String.valueOf(o);
    }

    private static String getCell(Row r, int i, DataFormatter fmt){
        if (r.getCell(i)==null) return null;
        String s = fmt.formatCellValue(r.getCell(i));
        return s==null?null:s.trim();
    }

    private static Integer parseInt(String s){
        try { return s==null?null:Integer.parseInt(s); } catch (Exception e){ return null; }
    }

    private static Long parseLong(String s){
        try { return s==null?null:Long.parseLong(s); } catch (Exception e){ return null; }
    }

    private static java.math.BigDecimal parseDecimal(String s){
        try { return s==null?null:new java.math.BigDecimal(s); } catch (Exception e){ return null; }
    }
}


